/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package rsa2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alexander
 */
public class RSA2 {

    public static void main(String[] args) {
        //X = y^d mod n
        //Decrypt
        try {
            File file = new File("C:\\Users\\Alexander\\Desktop\\RSATest.txt");
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            String lines = "";
            while (line != null) {
                lines = lines + line + "\t";
                line = br.readLine();
            }
            br.close();

            //ArrayList words = new ArrayList();
            for (String word : lines.split("\t")) {
                int wordNum = Integer.parseInt(word);
                System.out.print("Number:   " + wordNum + "  to Word: " + convertCipherTextValue(wordNum) + "\n");
                //words.add(convertCipherTextValue(wordNum));
            }
        } catch (IOException ex) {
            Logger.getLogger(RSA2.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

//number is the given number you want to find the prime factors of
    public static ArrayList primeFactors(int number) {
        final ArrayList numberFactors = new ArrayList<>(); //array list to hold the factors of the number 
        for (int i = 2, previousI = 0; i <= number / i; i++) {
            while (0 == number % i) {                //while the number is a factor
                if (i != previousI) {           //checks to make sure that the value was not added already. this will eliminate the possibility of getting duplicates
                    numberFactors.add(i);	//in the array
                    previousI = i;		//set previousI to the i used.
                }
                number = number / i;
            }
        }
        if (number > 1) {                 //only adds the factor to the list if its not one
            numberFactors.add(number);   //one isn't added because every number has one as a factor.
        }
        return numberFactors;
    }

    /**
     * Finds the coefficients of ax+by=d for a (mod b) where d is the gcd(a,b)
     *
     * @param a is the base of which we want the inverse
     * @param b is the modulo
     * @return the array of coefficients
     */
    public static int[] findInverse(int a, int b) {
        int x = 0, y = 1, lastx = 1, lasty = 0;
        while (b != 0) {
            int quotient = a / b;

            int temp = a;
            a = b;
            b = temp % b;

            temp = x;
            x = lastx - quotient * x;
            lastx = temp;

            temp = y;
            y = lasty - quotient * y;
            lasty = temp;
        }

        int[] coefficients = {lastx, lasty, a};
        return coefficients;
    }
    
public static int[] extendedEuc(int p, int q) {
        int totalRemainder = 0;
        int stepRemainder = 0;
        int GCD = 0;

        //at the end of the algorithm, previousS will be the multiplicative inverse of x
        int s = 0;
        int previousS = 1;
        int temp;
        while (q != 0) {
            totalRemainder = p / q;//calculate this step's quotient
            GCD = stepRemainder;
            stepRemainder = p % q;//calculate this step's remainder
            temp = q;
            q = p % q;//calculate the new values of base and modulusNum
            p = temp;
            temp = s;
            s = previousS - (totalRemainder * s);            //calculate the new coefficient of a

            previousS = temp;
        }
        int[] array = new int[2];
        array[0] = GCD;
        array[1] = previousS;
        //An array of longs containing the gcd of x and y in the first position and the inverse of x mod y in the second position.
        return array;
    }
    
    
    /**
     * Finds the gcd of a and b
     *
     * @param a is one number
     * @param b is the second number
     * @return the greatest common divisor of the two inputs
     */
    /*
    public static long GCD(int a, int b) {

        long gcd = 0;
        int r = 0;

        a = Math.abs(a);
        b = Math.abs(b);

        while (true) {
            if (b == 0) {
                gcd = a;
                break;
            } else {
                r = a % b;
                a = b;
                b = r;
            }
        }

        return gcd;

    }

*/
    //method to get the integer value of a letter
//always coverted to lower case uses its ASCII value 
public static int convertToDigit(char c) {
        char letter = Character.toLowerCase(c);
        return (int) letter - 97;
    }

    //method to find the gcd of two numbers
    public static int euclideanAlgorithm(int p, int q) {
        while (q != 0) {
            int temp = q;
            q = p % q;
            p = temp;
        }
        return p;
    }


    //method to convert a set of 3 characters into a number
    public static int createPlainTextValue(char a, char b, char c) {
        int plain_text = (convertToDigit(a) * (26 * 26)) + (convertToDigit(b) * 26) + convertToDigit(c);
        return plain_text;
    }

    //convert the cipher text back to letters
    public static String convertCipherTextValue(int cipher_text) {
        int x = cipher_text / (26 * 26) + 97;
        int y = (cipher_text % (26 * 26)) / 26 + 97;
        int z = cipher_text % 26 + 97;

        //System.out.print( x + "\t" + y + "\t" + z + "\n");
        String s = Character.toString((char) x) + Character.toString((char) y) + Character.toString((char) z);
        return s;
    }
}
